#include <iostream>
#include <string>
#include <memory>

// -------------------- Document 类层次 --------------------

// 抽象产品：Document
class Document {
public:
    virtual void show() const = 0; // 显示文档内容
    virtual ~Document() {}
};

// 具体产品：HTMLDocument
class HTMLDocument : public Document {
private:
    std::string header;
    std::string textSection;
    std::string imageSection;
    std::string footer;
public:
    void addHeader(const std::string& h) { header = h; }
    void addTextSection(const std::string& text) { textSection = text; }
    void addImageSection(const std::string& img) { imageSection = img; }
    void addFooter(const std::string& f) { footer = f; }

    void show() const override {
        std::cout << "----- HTML Document -----\n";
        std::cout << header << "\n";
        std::cout << textSection << "\n";
        std::cout << imageSection << "\n";
        std::cout << footer << "\n";
        std::cout << "-------------------------\n";
    }
};

// 其他具体产品类可以在此处定义，例如 PDFDocument, WordDocument 等

// -------------------- 建造者类层次 --------------------

// 抽象建造者：DocumentBuilder
class DocumentBuilder {
public:
    virtual void buildHeader() = 0;
    virtual void buildTextSection() = 0;
    virtual void buildImageSection() = 0;
    virtual void buildFooter() = 0;
    virtual Document* getResult() = 0;
    virtual ~DocumentBuilder() {}
};

// 具体建造者：HTMLDocumentBuilder
class HTMLDocumentBuilder : public DocumentBuilder {
private:
    HTMLDocument* doc;
public:
    HTMLDocumentBuilder() { doc = new HTMLDocument(); }
    
    void buildHeader() override {
        doc->addHeader("<html><body>");
    }

    void buildTextSection() override {
        doc->addTextSection("<p>Some text</p>");
    }

    void buildImageSection() override {
        doc->addImageSection("<img src='image.jpg'/>");
    }

    void buildFooter() override {
        doc->addFooter("</body></html>");
    }

    Document* getResult() override {
        return doc;
    }
};

// 其他具体建造者可以在此处定义，例如 PDFDocumentBuilder, WordDocumentBuilder 等

// -------------------- Director 类 --------------------

// 导演类（可选）：Director
class Director {
private:
    DocumentBuilder* builder;
public:
    void setBuilder(DocumentBuilder* b) {
        builder = b;
    }

    void construct() {
        if (builder) {
            builder->buildHeader();
            builder->buildTextSection();
            builder->buildImageSection();
            builder->buildFooter();
        }
    }
};

// -------------------- 测试主函数 --------------------

int main() {
    // 创建具体建造者
    HTMLDocumentBuilder htmlBuilder;

    // 创建导演并设置建造者
    Director director;
    director.setBuilder(&htmlBuilder);

    // 指导建造过程
    director.construct();

    // 获取建造结果
    std::unique_ptr<Document> doc(htmlBuilder.getResult());

    // 显示文档内容
    doc->show();

    // 注意：由于使用了unique_ptr，Document对象会在这里自动销毁
    return 0;
}
